package com.yanqu.road.server.manger.banquet;

import com.alibaba.fastjson.JSON;
import com.yanqu.road.entity.DataStatus;
import com.yanqu.road.entity.banquet.*;
import com.yanqu.road.entity.banquet.cross.CrossFeastPartyTempData;
import com.yanqu.road.entity.banquet.invitation.BanquetChildInvitation;
import com.yanqu.road.entity.banquet.invitation.BanquetMarryInvitation;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.log.LogBanquetIntegral;
import com.yanqu.road.entity.player.PlayerState;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserBeauty;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.relatives.RelativesInfo;
import com.yanqu.road.entity.servercenter.TitleInfo;
import com.yanqu.road.entity.task.args.union.UnionActivityTaskArgs;
import com.yanqu.road.logic.bussiness.player.UserBanquetBussiness;
import com.yanqu.road.logic.bussiness.player.UserBanquetJoinBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.thread.ThreadTaskManger;
import com.yanqu.road.pb.banquet.BanquetProto;
import com.yanqu.road.pb.worldmessage.WorldMessageProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.banquet.BanquetModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.AttributeModule;
import com.yanqu.road.server.gameplayer.module.player.BeautyModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.relatives.RelativesModule;
import com.yanqu.road.server.gameplayer.module.xiaomian.XiaoMianModule;
import com.yanqu.road.server.logic.mail.MailManager;
import com.yanqu.road.server.manger.MultipleLanguageMgr;
import com.yanqu.road.server.manger.activity.curio.CurioMgr;
import com.yanqu.road.server.manger.config.TitleMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.marriage.MarriageMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.player.WorldMessageMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.rank.RankMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.server.pb.BanquetPb;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.server.timer.banquet.BanquetSyncMemberTask;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.UUIDHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 宴会
 */
public class BanquetMgr extends TempMgr {

    /**
     * 赴宴记录有效期  30天
     */
    public static long RECORD_EXPIRE_TIME = 30 * DateHelper.DAY_MILLIONS;

    //用户的互宴信息
    private static Map<Long,List<UserBanquetJoin>> userBanquetJoinMap;

    private static Map<String, UserBanquetData> userBanquetDataMap = new ConcurrentHashMap<>();

    private static Map<String, Map<Long, UserBanquetMember>> userBanquetMemberMap = new ConcurrentHashMap<>();

    private static Map<String, UserBanquetRecord> feastBanquetRecordMap;

    private static Map<String, Object> lockMap;

    private static RandomHelper random = new RandomHelper();

    private static ThreadTaskManger threadTaskManger;

    private static AtomicInteger taskId = new AtomicInteger(1);

    private static Map<String, CrossFeastPartyTempData> crossFeastPartyTempDataMap = new ConcurrentHashMap<>();

    public static Map<Long,UserBanquetRelationship> getUserBanquetRelationshipMap(long playerId){
        Map<Long,UserBanquetRelationship> userBanquetRelationshipMap = new ConcurrentHashMap<>();
        for(long fromUserId : userBanquetJoinMap.keySet()){
            for(UserBanquetJoin userBanquetJoin : userBanquetJoinMap.get(fromUserId)){
                long relationshipUserId = 0;
                int toOrFrom = 0;//去参加为1，被参加为2,0为无关
                if(userBanquetJoin.getUserId1() == playerId){
                    toOrFrom = 1 ;
                    relationshipUserId = userBanquetJoin.getUserId2();
                }else if (userBanquetJoin.getUserId2() == playerId){
                    toOrFrom = 2;
                    relationshipUserId = userBanquetJoin.getUserId1();
                }
                if(relationshipUserId != 0 && !userBanquetRelationshipMap.containsKey(relationshipUserId)){
                    UserBanquetRelationship info = new UserBanquetRelationship();
                    info.setUserId(relationshipUserId);
                    info.setTo(0);
                    info.setFrom(0);
                    userBanquetRelationshipMap.put(relationshipUserId,info);
                }
                if(toOrFrom != 0){
                    UserBanquetRelationship info = userBanquetRelationshipMap.get(relationshipUserId);
                    if(toOrFrom == 1){
                        info.setTo(info.getTo() + 1);
                    }else if(toOrFrom == 2){
                        info.setFrom(info.getFrom() + 1);
                    }
                }
            }
        }
        //有在开宴会的在界面上显示宴会
        for(UserBanquetData userBanquetData : userBanquetDataMap.values()){
            if(!isBanquetOver(userBanquetData.getBanquetId()) && BanquetConfigMgr.isServerNormalBanquet(userBanquetData.getType())){
                if(userBanquetRelationshipMap.containsKey(userBanquetData.getUserId())){
                    userBanquetRelationshipMap.get(userBanquetData.getUserId()).setBanquetId(userBanquetData.getBanquetId());
                }
            }
        }
        return userBanquetRelationshipMap;
    }

    private static void addUserBanquetJoin(Long userId1,Long userId2){
        synchronized (userBanquetJoinMap){
            UserBanquetJoin userBanquetJoin = new UserBanquetJoin();
            userBanquetJoin.setUserId1(userId1);
            userBanquetJoin.setUserId2(userId2);
            userBanquetJoin.setJoinTime(System.currentTimeMillis());
            userBanquetJoin.setInsertOption();
            if(!userBanquetJoinMap.containsKey(userId1)){
                userBanquetJoinMap.put(userId1,new ArrayList<>());
            }
            userBanquetJoinMap.get(userId1).add(userBanquetJoin);
        }
    }


    public static String getUserBanquetId(long userId){
        List<UserBanquetData> banquetList = new ArrayList<>(userBanquetDataMap.values());
        for(UserBanquetData data : banquetList){
            if(!isBanquetOver(data.getBanquetId()) && data.getUserId() == userId && isBanquetType(data.getType(),eBanquetType.ServerNormalBanquet.getValue())){
                return data.getBanquetId();
            }
        }
        return "";
    }

    public static UserBanquetData getUserBanquet(long userId){
        List<UserBanquetData> banquetList = new ArrayList<>(userBanquetDataMap.values());
        for(UserBanquetData data : banquetList){
            if(!isBanquetOver(data.getBanquetId()) && data.getUserId() == userId && isBanquetType(data.getType(),eBanquetType.ServerNormalBanquet.getValue())){
                return data;
            }
        }
        return null;
    }


    public static boolean isSelfJoin(long selfUserId, String banquetId) {
        if (userBanquetMemberMap.containsKey(banquetId) && userBanquetMemberMap.get(banquetId).containsKey(selfUserId)) {
            return true;
        }
        return false;
    }

    //同步剩下的宴会成员给客户端
    public static void syncBanquetMemberTask(long userId, String banquetId, int sendTime, int memNum, int page){
        if (threadTaskManger != null) {
            threadTaskManger.addTask(taskId.getAndIncrement(),new BanquetSyncMemberTask(userId, banquetId, sendTime, memNum, page));
        }
    }

    //宴会聊天同步消息给参加宴会的人
    public static void syncBanquetMemberChatMsg(String banquetId, WorldMessageProto.WorldMessageTempMsg.Builder msg){
        Map<Long, UserBanquetMember> memberMap = userBanquetMemberMap.get(banquetId);
        if(null != memberMap){
            for(UserBanquetMember member : memberMap.values()){
                GamePlayer player = GamePlayerMgr.getOnlinePlayer(member.getUserId());
                if(null != player){
                    player.sendPacket(Protocol.U_WORLD_MESSAGE_SYNC, msg);
                }
            }
        }
    }

    //获取盛宴的宴会，用于同步和登录下发
    public static Map<String,UserBanquetData> getBanquetBeast(){
        Map<String, UserBanquetData> resMap = new ConcurrentHashMap<>();
        List<UserBanquetData> banquetList = new ArrayList<>(userBanquetDataMap.values());
        for(UserBanquetData info : banquetList){
            if(!isBanquetOver(info.getBanquetId()) && BanquetConfigMgr.isServerFeastBanquet(info.getType())){
                resMap.put(info.getBanquetId(),info);
            }
        }
        return resMap;
    }

    public static void syncBanquetFeast(GamePlayer player) {
        player.sendPacket(Protocol.U_BANQUET_FEAST_SYNC, BanquetPb.parseBanquetFeastListRespMsg(player, getBanquetBeast()));
        if (hasFeastPartyRunning()) {
            player.sendPacket(CrossProtocol.C_CROSS_PARTY_FEAST_SYNC, BanquetProto.CrossPartySyncReqMsg.newBuilder());
        }
    }

    //用户进入场景
    public static int addBanquetScene(long userId,String banquetId){
        Object lockObject = getLockValue(banquetId);
        if(lockObject == null){
            return GameErrorCode.E_GAME_ERROR;
        }
        synchronized (lockObject){
            userBanquetDataMap.get(banquetId).addSceneUser(userId);
        }
        return 0;
    }

    //用户移除场景
    public static int removeAllBanquetScene(long userId){
        for(String banquetId : userBanquetDataMap.keySet()){
            if(!isBanquetOver(banquetId)){
                /*Object lockObject = lockMap.get(banquetId);
                if(lockObject != null){
                    synchronized (lockObject){
                        userBanquetDataMap.get(banquetId).removeSceneUser(userId);
                    }
                }*/
                try {
                    userBanquetDataMap.get(banquetId).removeSceneUser(userId);
                }catch (Exception e){
                    getLogger().error("宴会死锁改后报错{}",e.toString());
                }
            }
        }
        return 0;
    }

    //用户移除场景
    public static int removeBanquetScene(long userId,String banquetId){
        Object lockObject = getLockValue(banquetId);
        if(lockObject == null){
            return GameErrorCode.E_GAME_ERROR;
        }
        synchronized (lockObject){
            if(userBanquetDataMap.get(banquetId) != null){
                userBanquetDataMap.get(banquetId).removeSceneUser(userId);
            }
        }
        return 0;
    }

    //同步宴会中的用户消息
    public static void syncBanquetUser(UserBanquetData userBanquetData,UserBanquetMember userBanquetMember){
        BanquetProto.BanquetMemberSync.Builder msg = BanquetPb.parseBanquetMemberSyncResp(userBanquetData,userBanquetMember,getBanquetMemberCount(userBanquetData.getBanquetId()));
        for(long userId : userBanquetData.getSceneBanquetUser()){
            GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
            if(player != null && player.getState() == PlayerState.ONLINE){
                Long pingTime = player.getLastPingTime();
                Long nowTime = System.currentTimeMillis();
                if(nowTime - pingTime < 5*1000){//ping小于5秒才同步
                    player.sendPacket(Protocol.U_BANQUET_MEMBER_SYNC, msg);
                    continue;
                }
            }
            removeAllBanquetScene(userId);
        }
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userBanquetData.getUserId());
        if(player != null){
            syncSelfBanquet(player,userBanquetData);
            //本服宴会要通知
            if(BanquetConfigMgr.isServerNormalBanquet(userBanquetData.getType())){
                syncJoinNoticeOwner(player,userBanquetMember);
            }
        }
    }

    //刚进宴会的时候分批同步人数
    public static boolean syncBanquetMember(GamePlayer player,UserBanquetData userBanquetData,Map<Long, UserBanquetMember> userBanquetMemberMap){
        if(userBanquetData.isSceneUser(player.getUserId())){
            BanquetProto.BanquetMemberSync.Builder msg = BanquetPb.parseBanquetMemberSyncResp(userBanquetData,userBanquetMemberMap,getBanquetMemberCount(userBanquetData.getBanquetId()));
            player.sendPacket(Protocol.U_BANQUET_MEMBER_SYNC, msg);
            return true;
        }
        return false;
    }

    public static UserBanquetData getBanquet(String banquetId){
        return userBanquetDataMap.get(banquetId);
    }

    //宴会人数
    public static int getBanquetMemberCount(String banquetId){
        Map<Long,UserBanquetMember> memberMap = userBanquetMemberMap.get(banquetId);
        if(memberMap == null){
            return 0;
        }
        return memberMap.size();
    }

    public static UserBanquetMember getBanquetMember(String banquetId,long userId){
        if(userBanquetMemberMap.containsKey(banquetId)){
            return userBanquetMemberMap.get(banquetId).get(userId);
        }
        return null;
    }

    //获得参加宴会的用户，分页大小，第几页
    public static Map<Long,UserBanquetMember> getBanquetMemberMap(String banquetId,int groupNum,int groupId){
        List<UserBanquetMember> memberList = new ArrayList<>();
        if(!isBanquetOver(banquetId)){
            memberList = new ArrayList<>(userBanquetMemberMap.get(banquetId).values());
        }
        Map<Long,UserBanquetMember> groupMemberMap = new ConcurrentHashMap<>();
        memberList.sort(new MemberSort());
        if(groupNum <= 0){
            for(UserBanquetMember member : memberList){
                groupMemberMap.put(member.getUserId(),member);
            }
        }else{
            int startIndex = groupNum*(groupId - 1);
            for(int i = 0;i<groupNum;i++){
                if(memberList.size() > startIndex+i){
                    UserBanquetMember member = memberList.get(startIndex+i);
                    groupMemberMap.put(member.getUserId(),member);
                }
            }
        }
        return groupMemberMap;
    }

    public static void syncCrossFeastParty(Map<String, CrossFeastPartyTempData> tempDataMap) {
        crossFeastPartyTempDataMap = tempDataMap;
    }

    public static CrossFeastPartyTempData getFeastTempData(String banquetId) {
        return crossFeastPartyTempDataMap.get(banquetId);
    }

    public static boolean isCrossFeastPartyOver(String partyId) {
        CrossFeastPartyTempData data = crossFeastPartyTempDataMap.get(partyId);
        if (data == null) {
            return true;
        }
        if (System.currentTimeMillis() > data.getOverTime()) {
            return true;
        }
        return false;
    }

    public static boolean hasFeastPartyRunning() {
        for (CrossFeastPartyTempData data : new ArrayList<>(crossFeastPartyTempDataMap.values())) {
            if (System.currentTimeMillis() <= data.getOverTime()) {
                return true;
            }
        }
        return false;
    }

    //从小到大按照座位排序
    static class MemberSort implements Comparator<UserBanquetMember> {
        @Override
        public int compare(UserBanquetMember o1, UserBanquetMember o2) {
            if (o1.getPos() == o2.getPos()) {
                return 0;
            }
            if (o1.getPos() >= o2.getPos()) {
                return 1;
            }
            return -1;
        }
    }

    //把结束的宴会移除内存
    private static void clearBanquet(){
        for(UserBanquetData info : userBanquetDataMap.values()){
            //大于3小时的移除掉
            if(System.currentTimeMillis() - info.getOverTime() > 3*60*60*1000 && info.getOp() == DataStatus.None && info.isSendReward()){
                userBanquetDataMap.remove(info.getBanquetId());
                userBanquetMemberMap.remove(info.getBanquetId());
            }
        }
    }

    public static Map<String,UserBanquetData> getOverBanquetReward(GamePlayer player){
        Map<String,UserBanquetData> rewardBanquetMap = new ConcurrentHashMap<>();
        List<UserBanquetData> banquetList = new ArrayList<>(userBanquetDataMap.values());
        for(UserBanquetData data : banquetList){
            if(  data.getUserId() == player.getUserId() && !data.isSendReward()){
                rewardBanquetMap.put(data.getBanquetId(),getSelfReward(player,data));
            }
        }
        return rewardBanquetMap;
    }

    //获取自己开的宴会的奖励
    private static UserBanquetData getSelfReward(GamePlayer player,UserBanquetData banquet){
        BanquetModule banquetModule = player.getModule(BanquetModule.class);
        if(BanquetConfigMgr.isServerNormalBanquet(banquet.getType()) && banquetModule.isBanquetNormalFullSeat()){
            fullRobotSeat(banquet);
            banquetModule.addBanquetNormalNum();
        }
        banquet.setSendReward(true);
        BanquetInfo banquetInfo = BanquetConfigMgr.getBanquetInfo(banquet.getType());
        int addFullSeat = 0;
        if(banquet.getUserCount() == banquetInfo.getSeat()){
            addFullSeat = banquetInfo.getFulPopularity();
        }
        int addEndEffect = banquetInfo.getEndEffect();
        BigDecimal popularity = BigDecimal.valueOf(banquet.getPopularity());
        BigDecimal integral = BigDecimal.valueOf(banquet.getIntegral());
        popularity = popularity.multiply((BigDecimal.valueOf(1000+addFullSeat+addEndEffect))).divide(BigDecimal.valueOf(1000));
        integral = integral.multiply((BigDecimal.valueOf(1000+addFullSeat))).divide(BigDecimal.valueOf(1000));

        //奖励中也会配置人气和积分奖励,需要加到宴会中去
        long rewardPopularity = 0;
        long rewardIntegral = 0;
        //宴会结束后的奖励
        if(!"0".equals(banquetInfo.getEndReward())){
            String endRewardStr = BanquetConfigMgr.getEndReward(banquet.getUserCount(),banquet.getType());
            Property endReward = PropertyHelper.parseStringToProperty(endRewardStr);
            //要把宴会和人气的奖励合并起来合到宴会里面去
            rewardPopularity = endReward.getCountByGoodsId(GameConfig.BANQUET_POPULARITY).longValue();
            rewardIntegral = endReward.getCountByGoodsId(GameConfig.BANQUET_INTEGRAL).longValue();
            endReward.removeProperty(GameConfig.BANQUET_POPULARITY,BigInteger.valueOf(rewardPopularity));
            endReward.removeProperty(GameConfig.BANQUET_INTEGRAL,BigInteger.valueOf(rewardIntegral));
            player.getModule(CurrencyModule.class).addCurrency(endReward,eLogMoneyType.Banquet,eLogMoneyType.BanquetOpenEndReward);
            banquet.setEndReward(PropertyHelper.parsePropertyToString(endReward));
        }
        popularity = popularity.add(BigDecimal.valueOf(rewardPopularity));
        integral = integral.add(BigDecimal.valueOf(rewardIntegral));

        //只有本分私宴才有美女技能加成
        if(BanquetConfigMgr.isServerNormalBanquet(banquet.getType())){
            //美女技能加成
            double beautiesSkillAddition = getBanquetOpenSkillAddition(player);
            popularity = popularity.
                    multiply(BigDecimal.valueOf(1000).add(BigDecimal.valueOf(beautiesSkillAddition))).
                    divide(BigDecimal.valueOf(1000));
        }

        integral = integral.divide(BigDecimal.valueOf(1),0,BigDecimal.ROUND_UP);
        popularity = popularity.divide(BigDecimal.valueOf(1),0,BigDecimal.ROUND_UP);

        banquet.setPopularity(popularity.longValue());
        banquet.setIntegral(integral.longValue());
        player.getModule(AttributeModule.class).addAttribute(ePlayerAttrType.BanquetPopularity,popularity.longValue());
        long oldIntegral = player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.BanquetIntegral);
        player.getModule(AttributeModule.class).addAttribute(ePlayerAttrType.BanquetIntegral,integral.longValue());
        player.notifyListener(eGamePlayerEventType.BanquetIntegral.getValue(), integral.longValue());
        player.notifyListener(eGamePlayerEventType.UnionBanquetIntegral.getValue(), new UnionActivityTaskArgs(UnionActivityTaskArgs.TYPE_ADD_VALUE, integral.longValue(), player.getUserInfo().getUnionUid()));
        //小面任务
        player.getModule(XiaoMianModule.class).addBanquetScore(integral.longValue());

        banquet.setUserBanquetMemberMap(userBanquetMemberMap.get(banquet.getBanquetId()));
        if(BanquetConfigMgr.isServerNormalBanquet(banquet.getType())){
            player.getModule(BanquetModule.class).addBanquetRecord(banquet);
        }else{
            addFeastBanquetRecord(banquet);
        }
        //婚宴增加亲密度
        if(banquet.getType() == eBanquetInfoType.MarryBanquet.getValue()){
            BanquetMarryInvitation inv = (BanquetMarryInvitation)banquet.getInvitation();
            int addIntimacyValue = BanquetConfigMgr.getBeautyAddValue(banquet.getType());
            UserBeauty userBeauty = player.getModule(BeautyModule.class).getUserBeauty(inv.getBeautyId());
            player.getModule(BeautyModule.class).addIntimacy(userBeauty, addIntimacyValue, eLogMoneyType.Beauty.getValue(), eLogMoneyType.BeautyInvitation.getValue());
            player.getModule(BeautyModule.class).syncUserBeauty(userBeauty);
        }else if(banquet.getType() == eBanquetInfoType.ChildBanquet.getValue()){//状元宴增加孩子赚速
            BanquetChildInvitation inv = (BanquetChildInvitation)banquet.getInvitation();
            int addEarnSpeedRatio = BanquetConfigMgr.getChildAddRatio(banquet.getType());
            String earnSpeed = MarriageMgr.childBanquetAddEarnSpeed(player,inv.getChildUid(),addEarnSpeedRatio);
            banquet.setChildAddEarnSpeed(earnSpeed);
        }

        //宴会人气榜单
        RankMgr.changeUserRank(eBigRankType.Normal.getValue(), player.getUserId(), BigInteger.valueOf(player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.BanquetPopularity)), eRankType.Banquet.getValue(), "");
        player.notifyListener(eGamePlayerEventType.BanquetPopularityRank.getValue(),popularity.longValue());
        AutoLogMgr.add(new LogBanquetIntegral(player.getUserId(), oldIntegral, oldIntegral + integral.longValue(), integral.longValue(), eLogMoneyType.Banquet.getValue(), eLogMoneyType.BanquetOpenEndReward.getValue()));
        return banquet;
    }

    public static int getBanquetOpenSkillAddition(GamePlayer player) {
        int addition = player.getModule(BeautyModule.class).getIdentitySkillAddition(eSkillType.BeautyBanquetPopularitySkill.getValue(), 0);
        addition += CurioMgr.getSkillAdditionBySkillType(eSkillType.CurioOpenBanquetPopularitySkill.getValue(), player, 0);
        return addition;
    }

    public static void addFeastBanquetRecord(UserBanquetData userBanquetData){
        UserBanquetRecord userBanquetRecord = new UserBanquetRecord();
        userBanquetRecord.setBanquetId(userBanquetData.getBanquetId());
        userBanquetRecord.setType(userBanquetData.getType());
        userBanquetRecord.setUserId(userBanquetData.getUserId());
        userBanquetRecord.setMemberCount(userBanquetData.getUserCount());
        userBanquetData.setUserBanquetMemberMap(new ConcurrentHashMap<>());
        userBanquetRecord.setRecord(JSON.toJSONString(userBanquetData));
        userBanquetRecord.setOpenTime(userBanquetData.getOpenTime());
        userBanquetRecord.setOverTime(userBanquetData.getOverTime());
        userBanquetRecord.setInsertOption();
        feastBanquetRecordMap.put(userBanquetRecord.getBanquetId(),userBanquetRecord);
    }

    public static void addFeastBanquetRecord(UserBanquetRecord userBanquetRecord){
        feastBanquetRecordMap.put(userBanquetRecord.getBanquetId(),userBanquetRecord);
    }

    public static List<UserBanquetRecord> getFeastBanquetRecordList(int banquetType){
        List<UserBanquetRecord> recordList = new ArrayList<>(feastBanquetRecordMap.values());
        recordList.sort(new RecordSort());
        Map<String, UserBanquetRecord> typeRecordTypeMap = new ConcurrentHashMap<>();
        int count = 0;
        for(UserBanquetRecord record : recordList){
            long beginTime = System.currentTimeMillis() - RECORD_EXPIRE_TIME;
            if(record.getOpenTime() < beginTime){
                continue;
            }
            if(BanquetMgr.isBanquetType(record.getType(),banquetType)){
                typeRecordTypeMap.put(record.getBanquetId(),record);
            }
            count++;
            if(count >= GameConfig.BANQUET_RECORD_LIST_MAX){break;}
        }
        return new ArrayList<>(typeRecordTypeMap.values());
    }

    static class RecordSort implements Comparator<UserBanquetRecord> {
        @Override
        public int compare(UserBanquetRecord o1, UserBanquetRecord o2) {
            if (o1.getOpenTime() == o2.getOpenTime()) {
                return 0;
            }
            if (o1.getOpenTime() >= o2.getOpenTime()) {
                return -1;
            }
            return 1;
        }
    }

    //banquetType1本服普通宴会，2盛宴，3跨服宴会;判断宴会对应类型
    public static boolean isBanquetType(int banquetInfoId,int banquetType){
        if(eBanquetType.ServerNormalBanquet.getValue() == banquetType){
            return BanquetConfigMgr.isServerNormalBanquet(banquetInfoId);
        }else if(eBanquetType.ServerFeastBanquet.getValue() == banquetType){
            return BanquetConfigMgr.isServerFeastBanquet(banquetInfoId);
        }else if(eBanquetType.CrossBanquet.getValue() == banquetType){
            return BanquetConfigMgr.isCrossBanquet(banquetInfoId);
        }else if(eBanquetType.CrossUserBanquet.getValue() == banquetType){
            return BanquetConfigMgr.isCrossUserBanquet(banquetInfoId);
        }
        return false;
    }

    public static Map<String, CrossFeastPartyTempData> getCrossFeastPartyTempDataMap() {
        return crossFeastPartyTempDataMap;
    }

    public static Map<String, UserBanquetData> getBanquetOpen(int banquetType){
        Map<String, UserBanquetData> banquetMap = new ConcurrentHashMap<>();
        List<UserBanquetData> banquetList = new ArrayList<>(userBanquetDataMap.values());
        for(UserBanquetData data : banquetList){
            if(!isBanquetOver(data.getBanquetId()) && isBanquetType(data.getType(),banquetType)){
                banquetMap.put(data.getBanquetId(),data);
            }
        }
        return banquetMap;
    }

    //获取开启的宴会,优先将要结束的下发下去
    public static Map<String, UserBanquetData> getBanquetOpen(GamePlayer player,int banquetType,boolean isRelative){
        int count = 0;
        Map<String, UserBanquetData> banquetMap = new ConcurrentHashMap<>();
        List<UserBanquetData> banquetList = new ArrayList<>(userBanquetDataMap.values());
        banquetList.sort(new BanquetSort());
        for(UserBanquetData data : banquetList){
            if(!isBanquetOver(data.getBanquetId()) && data.getUserId() != player.getUserId() && isBanquetType(data.getType(),banquetType)){
                //是亲家的请求且不是亲家
                if(isRelative && !isRelative(player,data.getUserId())){
                    continue;
                }
                if(!isRelative && isRelative(player,data.getUserId())){
                    continue;
                }
                banquetMap.put(data.getBanquetId(),data);
                count++;
            }
            if(count >= GameConfig.BANQUET_LIST_MAX){
                break;
            }
        }
        return banquetMap;
    }

    //同一個商會的和親家的會顯示在同一個頁簽
    public static boolean isRelative(GamePlayer player,long relativesId){
        RelativesInfo relativesInfo = player.getModule(RelativesModule.class).getRelativesInfo(relativesId);
        if (relativesInfo != null && relativesInfo.getStatus() == 1) {
            return true;
        }
        if(CrossUnionMgr.isSameUnion(player.getUserId(),relativesId)){
            return true;
        }
        return false;
    }

    //宴会按照结束时间从小到大排序
    static class BanquetSort implements Comparator<UserBanquetData> {
        @Override
        public int compare(UserBanquetData o1, UserBanquetData o2) {
            if (o1.getOverTime() == o2.getOverTime()) {
                return 0;
            }
            if (o1.getOverTime() >= o2.getOverTime()) {
                return 1;
            }
            return -1;
        }
    }

    //通知开宴会者有人来参加了
    public static void syncJoinNoticeOwner(GamePlayer player,UserBanquetMember userBanquetMember){
        //机器人不发
        if(!userBanquetMember.isRobot()){
            player.sendPacket(Protocol.U_BANQUET_JOIN_NOTICE_OWNER, BanquetPb.parseBanquetJoinNoticeOwnerMsg(userBanquetMember));
        }
    }

    public static void syncSelfBanquet(GamePlayer player,UserBanquetData nowBanquet){
        List<UserBanquetData> banquetList = new ArrayList<>(userBanquetDataMap.values());
        List<UserBanquetData> selfBanquetList = new ArrayList<>();
        for(UserBanquetData info :banquetList){
            //最后一个人参加就结束的也要同步
            if(nowBanquet != null && nowBanquet.getBanquetId().equals(info.getBanquetId()) && BanquetMgr.isBanquetOver(info.getBanquetId())){
                selfBanquetList.add(info);
            }
            if(!BanquetMgr.isBanquetOver(info.getBanquetId()) && info.getUserId() == player.getUserId()){
                selfBanquetList.add(info);
            }
        }
   //     player.sendChannelPacket(Protocol.U_BANQUET_SELF_SYNC, BanquetPb.parseSyncSelfBanquet(player,selfBanquetList));
        //顺便去跨服看一下吧
        player.sendPacket(CrossProtocol.C_CROSS_PARTY_SYNC_SELF,BanquetPb.parseSyncSelfBanquet(player,selfBanquetList));
    }

    public static boolean isBanquetOver(String banquetId){
        UserBanquetData userBanquetData = userBanquetDataMap.get(banquetId);
        if(userBanquetData == null){
            return true;
        }
        if(userBanquetData.getOverTime() < System.currentTimeMillis()){
            return true;
        }
        BanquetInfo banquetInfo = BanquetConfigMgr.getBanquetInfo(userBanquetData.getType());
        if(banquetInfo == null){
            return true;
        }
        if(banquetInfo.getSeat() != 0 && userBanquetData.getUserCount() >= banquetInfo.getSeat()){
            return true;
        }
        return false;
    }

    //本服盛宴和普通宴会和跨服宴会
    private static boolean canOpenBanquet(long userId,int type){
        List<UserBanquetData> banquetList = new ArrayList<>(userBanquetDataMap.values());
        for(UserBanquetData data : banquetList){
            if(!isBanquetOver(data.getBanquetId()) && data.getUserId() == userId && BanquetConfigMgr.isTheSameType(data.getType(),type)){
                return false;
            }
        }
        return true;
    }

    public static int openBanquet(GamePlayer player,int type,String invitationId){
        BanquetModule banquetModule = player.getModule(BanquetModule.class);
        if(BanquetConfigMgr.isBanquetInvitation(type)){
            if(!banquetModule.checkUserInvitation(invitationId,type)){
                return GameErrorCode.E_BANQUET_INVITATION;
            }
        }
        BanquetInfo banquetInfo = BanquetConfigMgr.getBanquetInfo(type);
        if(banquetInfo == null){
            return GameErrorCode.E_BANQUET_INFO_ERROR;
        }
        if(!canOpenBanquet(player.getUserId(),type)){
            return GameErrorCode.E_BANQUET_ONLY_ONE;
        }
        if(!"0".equals(banquetInfo.getOpenConsume())){
            if(!player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(banquetInfo.getOpenConsume()),
                    eLogMoneyType.Banquet,eLogMoneyType.BanquetOpenConsume)){
                return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
            }
        }

        //假如是请帖开启要保存请帖类型
        String invitationInfo = "";
        if(BanquetConfigMgr.isBanquetInvitation(type)){
            invitationInfo = banquetModule.useUserInvitation(invitationId,type);
        }


        UserBanquetData userBanquetData = new UserBanquetData();
        userBanquetData.setBanquetId(UUIDHelper.randomUUID(String.valueOf(GameServer.getInstance().getServerId())));
        UserInfo userInfo = player.getUserInfo();
        userBanquetData.setUserId(userInfo.getUserId());
        userBanquetData.setOpenTime(System.currentTimeMillis());
        userBanquetData.setOverTime(System.currentTimeMillis() + banquetInfo.getBanquetTime()*1000);
        userBanquetData.setInvitationId(invitationId);
        userBanquetData.setSendReward(false);
        userBanquetData.setType(type);
        userBanquetData.setPopularity(0);
        userBanquetData.setIntegral(0);
        userBanquetData.setUserCount(0);
        userBanquetData.setInvitationInfo(invitationInfo);
        userBanquetData.setUserBaseInfo(UserMgr.parseUserBaseInfo(userInfo,GameServer.getInstance().getServerId()));
        userBanquetData.setInsertOption();

        userBanquetDataMap.put(userBanquetData.getBanquetId(),userBanquetData);
        userBanquetMemberMap.put(userBanquetData.getBanquetId(),new ConcurrentHashMap<>());
        addLockValue(userBanquetData.getBanquetId());

        syncSelfBanquet(player,null);
        WorldMessageMgr.worldNotify(player, eMessageType.BanquetOpenNotice.getValue(), player.getUserInfo().getCity(), player.getTitleId(),
                player.getUserInfo().getNickName(), userBanquetData.getType(),userBanquetData.getBanquetId());
        if(BanquetConfigMgr.isServerFeastBanquet(userBanquetData.getType())){
            List<GamePlayer> playerList = GamePlayerMgr.getCopyPlayerList();
            for(GamePlayer player1 : playerList){
                syncBanquetFeast(player1);
            }
        }
        return 0;
    }

    public static int joinBanquet(GamePlayer player, String banquetId, int giftId){
        Object lockObject = getLockValue(banquetId);
        if(lockObject == null){
            return GameErrorCode.E_GAME_ERROR;
        }
        synchronized (lockObject){
            UserBanquetData userBanquetData = userBanquetDataMap.get(banquetId);
            if(userBanquetData != null){
                Map<Long,UserBanquetMember> memberMap = userBanquetMemberMap.get(banquetId);
                BanquetInfo banquetInfo = BanquetConfigMgr.getBanquetInfo(userBanquetData.getType());
                BanquetGiftInfo banquetGiftInfo = BanquetConfigMgr.getBanquetGiftInfo(userBanquetData.getType(),giftId);
                if(player.getUserId() == userBanquetData.getUserId() && BanquetConfigMgr.isServerNormalBanquet(banquetInfo.getId())){
                    return  GameErrorCode.E_BANQUET_JOIN_SELF;
                }
                if(banquetInfo == null){
                    return GameErrorCode.E_BANQUET_INFO_ERROR;
                }
                if(banquetGiftInfo == null){
                    return GameErrorCode.E_BANQUET_GIFT_ERROR;
                }
                if(memberMap.size() >= banquetInfo.getSeat() && banquetInfo.getSeat() != 0){
                    return GameErrorCode.E_BANQUET_MAX_SEAT;
                }
                if(memberMap.containsKey(player.getUserId())){
                    return GameErrorCode.E_BANQUET_HAS_JOIN;
                }
                if(!"0".equals(banquetGiftInfo.getJoinConsume())){
                    if(!player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(banquetGiftInfo.getJoinConsume()),
                            eLogMoneyType.Banquet,eLogMoneyType.BanquetJoinConsume)){
                        return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
                    }
                }

                UserBanquetMember userBanquetMember = new UserBanquetMember();
                userBanquetMember.setBanquetId(banquetId);
                UserInfo userInfo = player.getUserInfo();
                userBanquetMember.setUserId(userInfo.getUserId());
                userBanquetMember.setGiftId(giftId);
                userBanquetMember.setRobot(false);
                userBanquetMember.setRobotProcessId(0);
                userBanquetMember.setRobotId(0);
                userBanquetMember.setPos(memberMap.size()+1);
                userBanquetMember.setPopularity(0);
                userBanquetMember.setIntegral(0);
                userBanquetMember.setUserBaseInfo(UserMgr.parseUserBaseInfo(userInfo,GameServer.getInstance().getServerId()));
                if(!"0".equals(banquetGiftInfo.getJoinScore())){
                    int titleAdd = 0;
                    if(banquetInfo.isTitleAdd()){
                        //随礼的奖励值加上头衔加成千分比
                        TitleInfo titleInfo = TitleMgr.getTitleInfo(player.getTitleId());
                        //头衔加成
                        titleAdd = titleInfo.getBanquetEffect();
                    }
                    Property joinScore = PropertyHelper.parseStringToProperty(banquetGiftInfo.getJoinScore());
                    BigDecimal popularity = BigDecimal.valueOf(joinScore.getCountByGoodsId(GameConfig.BANQUET_POPULARITY).longValue());
                    BigDecimal integral = BigDecimal.valueOf(joinScore.getCountByGoodsId(GameConfig.BANQUET_INTEGRAL).longValue());
                    popularity = popularity.multiply((BigDecimal.valueOf(1000+titleAdd))).divide(BigDecimal.valueOf(1000));
                    integral = integral.multiply((BigDecimal.valueOf(1000+titleAdd))).divide(BigDecimal.valueOf(1000));

                    //只有本分私宴才有门客技能加成
                    if(BanquetConfigMgr.isServerNormalBanquet(userBanquetData.getType())){
                        //门客技能加成
                        int skillAddition = getBanquetJoinSkillAddition(player);
                        popularity = popularity.
                                multiply(BigDecimal.valueOf(1000).add(BigDecimal.valueOf(skillAddition))).
                                divide(BigDecimal.valueOf(1000));
                    }
                    integral = integral.divide(BigDecimal.valueOf(1),0,BigDecimal.ROUND_UP);
                    popularity = popularity.divide(BigDecimal.valueOf(1),0,BigDecimal.ROUND_UP);
                    userBanquetMember.setPopularity(popularity.longValue());
                    userBanquetMember.setIntegral(integral.longValue());
                    player.getModule(AttributeModule.class).addAttribute(ePlayerAttrType.BanquetPopularity,popularity.longValue());
                    long oldIntegral = player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.BanquetIntegral);
                    player.getModule(AttributeModule.class).addAttribute(ePlayerAttrType.BanquetIntegral,integral.longValue());
                    player.notifyListener(eGamePlayerEventType.BanquetIntegral.getValue(), integral.longValue());
                    player.notifyListener(eGamePlayerEventType.UnionBanquetIntegral.getValue(), new UnionActivityTaskArgs(UnionActivityTaskArgs.TYPE_ADD_VALUE, integral.longValue(), player.getUserInfo().getUnionUid()));
                    //小面任务
                    player.getModule(XiaoMianModule.class).addBanquetScore(integral.longValue());
                    //普通的本服宴会是所有人的积分加起来
                    if(BanquetConfigMgr.isServerNormalBanquet(userBanquetData.getType())){
                        //宴会加上人气和积分
                        userBanquetData.setPopularity(userBanquetData.getPopularity()+popularity.longValue());
                        userBanquetData.setIntegral(userBanquetData.getIntegral()+integral.longValue());
                    }

                    //宴会人气榜单
                    RankMgr.changeUserRank(eBigRankType.Normal.getValue(), player.getUserId(), BigInteger.valueOf(player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.BanquetPopularity)), eRankType.Banquet.getValue(), "");
                    player.notifyListener(eGamePlayerEventType.BanquetPopularityRank.getValue(),popularity.longValue());
                    AutoLogMgr.add(new LogBanquetIntegral(player.getUserId(), oldIntegral, oldIntegral + integral.longValue(), integral.longValue(), eLogMoneyType.Banquet.getValue(), eLogMoneyType.BanquetJoinReward.getValue()));
                }
                userBanquetMember.setInsertOption();
                userBanquetMemberMap.get(banquetId).put(userBanquetMember.getUserId(),userBanquetMember);

                userBanquetData.setUserCount(memberMap.size());

                if(!"0".equals(banquetGiftInfo.getJoinReward())){
                    Property joinReward = PropertyHelper.parseStringToProperty(BanquetConfigMgr.getJoinReward(memberMap.size(),giftId));
                    player.getModule(CurrencyModule.class).addCurrency(joinReward,eLogMoneyType.Banquet,eLogMoneyType.BanquetJoinReward);
                }

                //人满了直接发满员幸运奖励
                if(memberMap.size() == banquetInfo.getSeat()){
                    sendLuckUserReward(banquetInfo,userBanquetData,memberMap);
                }
                syncBanquetUser(userBanquetData,userBanquetMember);
                if(BanquetConfigMgr.isServerFeastBanquet(userBanquetData.getType())){
                    popRewardSync(userBanquetData);
                }
                if(BanquetConfigMgr.isServerNormalBanquet(userBanquetData.getType())){
                    addUserBanquetJoin(player.getUserId(),userBanquetData.getUserId());
                }
            }
        }
        return 0;
    }

    /**
     * 赴宴人气加成
     */
    public static int getBanquetJoinSkillAddition(GamePlayer player) {
        int skillAddition = player.getModule(PatronsModule.class).getTalentSkillAddition(eSkillType.BanquetJoinPopularitySkill.getValue(), 0);   //天赋
        skillAddition += player.getModule(BeautyModule.class).getIdentitySkillAddition(eSkillType.BanquetJoinPopularitySkill.getValue(), 0);        //美名
        skillAddition += CurioMgr.getSkillAdditionBySkillType(eSkillType.CurioJoinBanquetPopularitySkill.getValue(), player, 0);
        return skillAddition;
    }

    //人气礼同步
    private static void popRewardSync(UserBanquetData banquetData){
        if(BanquetConfigMgr.isSendBanquetFeastRewardPoint(banquetData.getUserCount())){
            List<Long> playerIdList = GamePlayerMgr.getAllOnlinePlayerId();
            for(Long userId : playerIdList){
                GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
                player.getModule(BanquetModule.class).banquetPopRewardSync(banquetData);
            }
        }
    }

    //获取满座幸运者
    private static UserBanquetMember getLuckMember(Map<Long,UserBanquetMember> memberMap){
        Map<Long,UserBanquetMember> userMap = new ConcurrentHashMap<>();
        long i = 1;
        for(UserBanquetMember member : memberMap.values()){
            if(!member.isRobot()){
                userMap.put(i++,member);
            }
        }
        long randomLuckPos = random.next(1, userMap.size()+1);
        return userMap.get(randomLuckPos);
    }

    private static void sendLuckUserReward(BanquetInfo banquetInfo,UserBanquetData userBanquetData,Map<Long,UserBanquetMember> memberMap){
        if(!"0".equals(banquetInfo.getLockReward())){
            UserBanquetMember memberInfo = getLuckMember(memberMap);
            if (memberInfo == null){
                return;
            }
            UserInfo userInfo = UserMgr.getUserInfo(memberInfo.getUserId());
            UserInfo userBanquetInfo = UserMgr.getUserInfo(userBanquetData.getUserId());
            String mailTitle = MultipleLanguageMgr.getContent(MailManager.BANQUET_LUCK_USER_TITLE, userInfo.getLanguage());
            String banquetName = MultipleLanguageMgr.getContent(banquetInfo.getName(), userInfo.getLanguage());
            String mailContent = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.BANQUET_LUCK_USER_CONTENT, userInfo.getLanguage()),
                    userBanquetInfo.getNickName(),banquetName);
            MailManager.sendMail(memberInfo.getUserId(), eMailType.SYSTEM.getValue(), banquetInfo.getLockReward(), mailContent, mailTitle);
        }
    }

    //获取是否要触发机器人
    private static int getRobotsConditionProcessId(UserBanquetData userBanquetData){
        BanquetInfo banquetInfo = BanquetConfigMgr.getBanquetInfo(userBanquetData.getType());
        Map<Integer, List<Integer>> processMap = BanquetConfigMgr.getRobotCondtion();
        Map<Long,UserBanquetMember> memberMap = userBanquetMemberMap.get(userBanquetData.getBanquetId());
        for(Integer processId : processMap.keySet()){
            //是否有机器人了
            boolean robotFlag = false;
            List<Integer> processList = processMap.get(processId);
            long timePass = BigInteger.valueOf(userBanquetData.getOverTime() - userBanquetData.getOpenTime()).multiply(BigInteger.valueOf(processList.get(0))).divide(BigInteger.valueOf(100)).longValue();
            long timeProcess = timePass + userBanquetData.getOpenTime();
            if(System.currentTimeMillis() < timeProcess){
                continue;
            }
            long seatPass = BigDecimal.valueOf(banquetInfo.getSeat()).multiply(BigDecimal.valueOf(processList.get(1))).divide(BigDecimal.valueOf(100),0,BigDecimal.ROUND_UP).longValue();
            if(memberMap.size() >= seatPass){
                continue;
            }
            for(UserBanquetMember member : memberMap.values()){
                if(member.isRobot() && processId == member.getRobotProcessId()){
                    robotFlag = true;
                    break;
                }
            }
            if(!robotFlag){
                return processId;
            }
        }
        return 0;
    }

    private static void robotsJoin(){
        List<UserBanquetData> banquetList = new ArrayList<>(userBanquetDataMap.values());
        for(UserBanquetData data : banquetList){
            Object object = getLockValue(data.getBanquetId());
            if(object != null){
                synchronized (object){
                    if(BanquetConfigMgr.isServerFeastBanquet(data.getType()) && !isBanquetOver(data.getBanquetId())){
                        /*if(data.getUserCount() < 500){
                            int addCount = 20;
                            for(int i=0;i<addCount;i++){
                                robotsJoinBanquetTemp(data);
                            }
                        }*/
                    }
                    if(BanquetConfigMgr.isServerNormalBanquet(data.getType()) && !isBanquetOver(data.getBanquetId())){
                        int processId = getRobotsConditionProcessId(data);
                        if(processId != 0){
                            robotsJoinBanquet(processId,data);
                        }
                    }
                }
            }
        }
    }


    public static UserBaseInfo initRobotUserInfo(){
        UserBaseInfo userBaseInfo = new UserBaseInfo();
        userBaseInfo.setUserAliasId(0);
        userBaseInfo.setNickName("");
        userBaseInfo.setTitleId(0);
        userBaseInfo.setDecoration("");
        userBaseInfo.setUnionAliasId(0);
        userBaseInfo.setUnionUid("");
        userBaseInfo.setUnionName("");
        userBaseInfo.setVipExp(0);
        userBaseInfo.setSex(0);
        userBaseInfo.setEarnSpeed(BigInteger.ZERO);
        userBaseInfo.setRegisterTime(0);
        userBaseInfo.setServerId(0);
        userBaseInfo.setWorld("");
        userBaseInfo.setContinent("");
        userBaseInfo.setCountry("");
        userBaseInfo.setProvince("");
        userBaseInfo.setCity("");
        userBaseInfo.setLastLoginTime(0);
        userBaseInfo.setHideVipAndAddress(0);
        return userBaseInfo;
    }


    private static void fullRobotSeat(UserBanquetData banquet){
        BanquetInfo banquetInfo = BanquetConfigMgr.getBanquetInfo(banquet.getType());
        int needAdd = banquetInfo.getSeat() - banquet.getUserCount();
        for(int i = 0;i < needAdd;i++){
            robotsJoinBanquet(banquet.getUserCount()+1,banquet);
        }
    }

    //机器人加入宴会用机器人测试用
    private static void robotsJoinBanquetTemp(UserBanquetData userBanquetData){
        robotsJoinBanquet(userBanquetData.getUserCount()+1,userBanquetData);
    }

    private static void robotsJoinBanquet(int processId,UserBanquetData userBanquetData){
        Object lockObj = getLockValue(userBanquetData.getBanquetId());
        if(lockObj != null){
            synchronized (lockObj){
                BanquetInfo banquetInfo = BanquetConfigMgr.getBanquetInfo(userBanquetData.getType());
                if(banquetInfo == null){
                    return;
                }
                List<Integer> robotList = StringUtils.stringToIntegerList(banquetInfo.getRobots(),"=");
                BanquetGiftInfo banquetGiftInfo = BanquetConfigMgr.getBanquetGiftInfo(userBanquetData.getType(),robotList.get(1));
                if(banquetGiftInfo == null){
                    return;
                }
                if(userBanquetData.getUserCount() >= banquetInfo.getSeat() && banquetInfo.getSeat() != 0){
                    return;
                }
                Map<Long,UserBanquetMember> memberMap = userBanquetMemberMap.get(userBanquetData.getBanquetId());
                UserBanquetMember userBanquetMember = new UserBanquetMember();
                userBanquetMember.setBanquetId(userBanquetData.getBanquetId());
                userBanquetMember.setUserId(processId);
                userBanquetMember.setGiftId(robotList.get(1));
                userBanquetMember.setRobot(true);
                userBanquetMember.setRobotProcessId(processId);
                userBanquetMember.setRobotId(robotList.get(0));
                userBanquetMember.setPos(memberMap.size()+1);
                userBanquetMember.setPopularity(0);
                userBanquetMember.setIntegral(0);
                userBanquetMember.setUserBaseInfo(initRobotUserInfo());
                if(!"0".equals(banquetGiftInfo.getJoinScore())){
                    //随礼的奖励值加上头衔加成千分比
                    Property joinScore = PropertyHelper.parseStringToProperty(banquetGiftInfo.getJoinScore());
                    long popularity = joinScore.getCountByGoodsId(GameConfig.BANQUET_POPULARITY).longValue();
                    long integral = joinScore.getCountByGoodsId(GameConfig.BANQUET_INTEGRAL).longValue();
                    userBanquetMember.setPopularity(popularity);
                    userBanquetMember.setIntegral(integral);
                    if(BanquetConfigMgr.isServerNormalBanquet(userBanquetData.getType())){
                        //宴会加上人气和积分
                        userBanquetData.setPopularity(userBanquetData.getPopularity()+popularity);
                        userBanquetData.setIntegral(userBanquetData.getIntegral()+integral);
                    }
                }
                userBanquetMember.setInsertOption();
                memberMap.put(userBanquetMember.getUserId(),userBanquetMember);

                userBanquetData.setUserCount(memberMap.size());

                //人满了直接发满员幸运奖励
                if(memberMap.size() == banquetInfo.getSeat()){
                    sendLuckUserReward(banquetInfo,userBanquetData,memberMap);
                }
                syncBanquetUser(userBanquetData,userBanquetMember);
            }
        }
    }

    //删除过期的参加宴会记录，本服诗人宴会
    private static void removeExpireJoinRecord(){
        long expireTime = System.currentTimeMillis() - (long)GameConfig.BANQUET_RELATIONSHIP_EXPIRE_TIME * 24 * 60 * 60 * 1000;
        synchronized (userBanquetJoinMap){
            for(List<UserBanquetJoin> userBanquetJoinList : userBanquetJoinMap.values()){
                Iterator<UserBanquetJoin> iterator = userBanquetJoinList.iterator();
                while (iterator.hasNext()) {
                    UserBanquetJoin info = iterator.next();
                    if (info.getJoinTime() < expireTime) {
                        iterator.remove();//使用迭代器的删除方法删除
                    }
                }
            }
        }
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    public boolean save() {
        robotsJoin();
        clearBanquet();
        List<UserBanquetData> banquetList = new ArrayList<>(userBanquetDataMap.values());
        for(UserBanquetData userBanquetData : banquetList){
            if(userBanquetData.getOp() == DataStatus.Insert){
                UserBanquetBussiness.addUserBanquet(userBanquetData);
            }else if(userBanquetData.getOp() == DataStatus.Update){
                UserBanquetBussiness.updateUserBanquet(userBanquetData);
            }
        }
        List<Map<Long, UserBanquetMember>> banquetMemberMap = new ArrayList<>(userBanquetMemberMap.values());
        for(Map<Long, UserBanquetMember> userMap : banquetMemberMap){
            List<UserBanquetMember> memberList = new ArrayList<>(userMap.values());
            for(UserBanquetMember userBanquetMember : memberList){
                if(userBanquetMember.getOp() == DataStatus.Insert){
                    UserBanquetBussiness.addUserBanquetMember(userBanquetMember);
                }else if(userBanquetMember.getOp() == DataStatus.Update){
                    UserBanquetBussiness.updateUserBanquetMember(userBanquetMember);
                }
            }
        }
        List<UserBanquetRecord> banquetRecordList = new ArrayList<>(feastBanquetRecordMap.values());
        for (UserBanquetRecord data : banquetRecordList) {
            if (data.isInsertOption()) {
                UserBanquetBussiness.addUserBanquetRecord(data);
            }
        }

        removeExpireJoinRecord();
        for(List<UserBanquetJoin> dataList : userBanquetJoinMap.values()){
            for(UserBanquetJoin data : dataList){
                if(data.getOp() == DataStatus.Insert){
                    UserBanquetJoinBussiness.addUserBanquetJoin(data);
                }else if(data.getOp() == DataStatus.Update){
                    UserBanquetJoinBussiness.updateUserBanquetJoin(data);
                }
            }
        }
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean reloadData() {
        if (threadTaskManger == null) {
            threadTaskManger = new ThreadTaskManger(2, "WorldMessageTaskManger");
        }
        userBanquetDataMap = UserBanquetBussiness.getRunningUserBanquetMap();
        String typeIn = BanquetConfigMgr.getBanquetIdIn(eBanquetType.ServerFeastBanquet.getValue());
        feastBanquetRecordMap = UserBanquetBussiness.getFeastBanquetRecord(typeIn);
        initUserBanquetMember();
        initLockMap();
        userBanquetJoinMap = UserBanquetJoinBussiness.getUserBanquetJoin();
        return true;
    }

    private static void initUserBanquetMember(){
        for(UserBanquetData data : userBanquetDataMap.values()){
            //本服盛宴不读取
            if(!BanquetConfigMgr.isServerNormalBanquet(data.getType()) && isBanquetOver(data.getBanquetId())){
                continue;
            }
            Map<Long, UserBanquetMember> userMap = UserBanquetBussiness.getUserBanquetMemberMap(data.getBanquetId());
            userBanquetMemberMap.put(data.getBanquetId(),userMap);
        }
    }

    private static void initLockMap() {
        lockMap = new HashMap<>();
        synchronized (lockMap) {
            for (Map.Entry<String, UserBanquetData> userBanquetDataInfo : userBanquetDataMap.entrySet()) {
                lockMap.put(userBanquetDataInfo.getKey(), new Object());
            }
        }

    }

    private static void addLockValue(String banquetId){
        synchronized (lockMap) {
            if(!lockMap.containsKey(banquetId)){
                lockMap.put(banquetId,new Object());
            }
        }

    }

    private static Object getLockValue(String banquetId){
        synchronized (lockMap) {
            if(lockMap.containsKey(banquetId)){
                return lockMap.get(banquetId);
            }
            lockMap.put(banquetId, new Object());
            return lockMap.get(banquetId);
        }

    }

    /**
     * 增加宴会举办次数
     */
    public static void addBanquetConductTimes(GamePlayer player){
        AttributeModule attributeModule = player.getModule(AttributeModule.class);
        attributeModule.addAttribute(ePlayerAttrType.BanquetTotalConductTimes, 1);
        player.notifyListener(eGamePlayerEventType.BanquetTotalConductTimes.getValue(), attributeModule.getAttribute(ePlayerAttrType.BanquetTotalConductTimes));
    }


    /**
     * 增加宴会参与次数 1次
     * @param player
     */
    public static void addBanquetJoinTimes(GamePlayer player){
        addBanquetJoinTimes(player,1);
    }

    /**
     * 增加宴会参与次数
     */
    public static void addBanquetJoinTimes(GamePlayer player,int times){
        player.notifyListener(eGamePlayerEventType.BanquetJoinTimes.getValue(), times);
        player.notifyListener(eGamePlayerEventType.UnionBanquetJoinTimes.getValue(), new UnionActivityTaskArgs(UnionActivityTaskArgs.TYPE_ADD_VALUE, times, player.getUserInfo().getUnionUid()));
        AttributeModule attributeModule = player.getModule(AttributeModule.class);
        attributeModule.addAttribute(ePlayerAttrType.BanquetTotalJoinTimes, times);
        player.notifyListener(eGamePlayerEventType.BanquetTotalJoinTimes.getValue(), attributeModule.getAttribute(ePlayerAttrType.BanquetTotalJoinTimes));
    }

    public static long getJoinPopularity(GamePlayer player, int type, int giftId) {
        BanquetInfo banquetInfo = BanquetConfigMgr.getBanquetInfo(type);
        BanquetGiftInfo banquetGiftInfo = BanquetConfigMgr.getBanquetGiftInfo(type, giftId);
        int titleAdd = 0;
        if(banquetInfo.isTitleAdd()){
            //随礼的奖励值加上头衔加成千分比
            TitleInfo titleInfo = TitleMgr.getTitleInfo(player.getTitleId());
            //头衔加成
            titleAdd = titleInfo.getBanquetEffect();
        }
        Property joinScore = PropertyHelper.parseStringToProperty(banquetGiftInfo.getJoinScore());
        BigDecimal popularity = BigDecimal.valueOf(joinScore.getCountByGoodsId(GameConfig.BANQUET_POPULARITY).longValue());
        popularity = popularity.multiply((BigDecimal.valueOf(1000+titleAdd))).divide(BigDecimal.valueOf(1000));

        //只有本分私宴才有门客技能加成
        if(BanquetConfigMgr.isServerNormalBanquet(type)){
            //门客技能加成
            int skillAddition = getBanquetJoinSkillAddition(player);
            popularity = popularity.
                    multiply(BigDecimal.valueOf(1000).add(BigDecimal.valueOf(skillAddition))).
                    divide(BigDecimal.valueOf(1000));
        }
        popularity = popularity.divide(BigDecimal.valueOf(1),0,BigDecimal.ROUND_UP);
        return popularity.longValue();
    }

    public static long getJoinIntegral(GamePlayer player, int type, int giftId) {
        BanquetInfo banquetInfo = BanquetConfigMgr.getBanquetInfo(type);
        BanquetGiftInfo banquetGiftInfo = BanquetConfigMgr.getBanquetGiftInfo(type, giftId);
        int titleAdd = 0;
        if(banquetInfo.isTitleAdd()){
            //随礼的奖励值加上头衔加成千分比
            TitleInfo titleInfo = TitleMgr.getTitleInfo(player.getTitleId());
            //头衔加成
            titleAdd = titleInfo.getBanquetEffect();
        }
        Property joinScore = PropertyHelper.parseStringToProperty(banquetGiftInfo.getJoinScore());
        BigDecimal integral = BigDecimal.valueOf(joinScore.getCountByGoodsId(GameConfig.BANQUET_INTEGRAL).longValue());
        integral = integral.multiply((BigDecimal.valueOf(1000+titleAdd))).divide(BigDecimal.valueOf(1000));
        integral = integral.divide(BigDecimal.valueOf(1),0,BigDecimal.ROUND_UP);
        return integral.longValue();
    }

}

